PECompact

©1999-2002 by Collake Software

All Rights Reserved.

Email: support@collakesoftware.com

Homepage:

http://www.CollakeSoftware.com/ 

 

 


This software is provided as-is, without warranty of ANY KIND, either expressed or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose. The author shall NOT be held liable for ANY damage to you, your computer, or to anyone or anything else, that may result from its use, or misuse. Basically, you use it at YOUR OWN RISK. Registration is required to continue using this software after a 14-day evaluation period has expired. Please see the registration information at the end of this document.


 

          I.      Overview

PECompact is a utility that compresses Windows 9x/NT4/w2k portable executables (EXE, DLL, SCR, OCX, etc..) significantly while leaving them 100% functional. PECompact’d applications occupy less disk space, cost less to distribute, are more fault tolerant, are loaded quicker across networks, decrease network traffic, and are more difficult to reverse-engineer and modify.

 

PECompact works by compressing the code, data, import directory, selected resources, and other portions of Windows portable executables. At runtime, the executable is rebuilt in memory with no noticeable delay; the executable is at no time extracted to disk. In fact, compressed executables can actually load quicker in some cases because there is less data to be retrieved from the disk or network, which is usually the largest bottleneck. Both compression algorithms used by PECompact feature an optimized, 32bit x86 assembly language decompressor for maximum data throughput.

 

This tool is highly configurable and gives the user a great deal of power to select what and how things are compressed. PECompact also has unique plug-in support to allow users to supply their own encryption/decryption procedures or special functionality to compressed executables.

 

For users who prefer not to compress their executables for whatever reason, PECompact also offers a “Trim Only” option that optimizes the executable structure and decreases its size without applying any compression at all! This function can optionally strip relocations from the executable.

 

 

Features

 

     II.      Usage

PECompact analyzes the target executable and auto-configures itself for those users who prefer not to get involved with the intricate details of the compression. However, to support more advanced users, PECompact is the most configurable executable compressor on the market.

A.                       Options

 

 

1.      The Main Dialog

 

Function Name                       Description

Compress Normal Application

Compress file as a normal EXE.

Compress DLL/OCX

Compress file as a Dynamic-Link Library or OCX control.

Trim Only

Realign and optimize the executable structure without applying any compression or installing any symbiotic code. Relocations are stripped from EXEs, and left preserved in DLLs.

aPLib

Utilize Joergen Ibsen’s aPLib data compression library. This compression library is fast and tight, especially for files smaller than 64k. This option can also be selected by using the command line switch “/J”.

JCALG1

Utilize Jeremy Collake’s JCALG1 compression library. This compression library supports multiple compress level settings and performs better than aPLib on larger files. This option can also be selected by using the command line switch “/J-“.

Compression Level

This trackbar allows the user to select the compression level that JCALG1 will use. A higher level (farther to the right) will use a larger window size, thereby increasing the compression level but decreasing the compression speed. Note that higher compression levels will require significantly more memory during compression. Decompression speed and memory requirements are unaffected.

Browse

Browse for and select a file to compress or trim.

Compress/Trim

Begin compression or trimming of an executable.

Test

Test the compressed executable, with an option to restore the backup.

Erase .BAK

Erase backup of compressed executable.

Exit

Exit PECompact.

Advanced Configuration

Show the advanced configuration dialog. See below for explanation of options there.

 

2.      Advanced Configuration

 

Create New Section

Places the PECompact symbiotic code into a new section of the executable rather than the default of appending it to the last section. Checking this option may result in a slightly larger compressed executable.

Restructure Resources

Restructure the resources in a more compressible format. Turning this option off will hinder compression of some resources in the executable.

Merge Sections

Merge congruent, compressible sections into one section to reduce file alignment overhead. Turning this option off will result in a larger compressed executable, but slightly faster loading.

Strip Relocations

Strip the relocations (fixups) from the executable. It is safe to strip the relocations from EXEs, but one should NEVER strip the relocations from DLLs.

Compress Export Table

Compress the export table, if it exists. This option is not recommended.

Relocate Export Table

The export table is moved to an uncompressed area of the file so that the section originally containing the export table may be compressed. This results in better compression.

Use Windows DLL Loader

Allow the windows loader to process the import directory instead of the PECompact symbiotic code.

Copy Overlay

Some executables, such as setup applications, have extra data appended to the end. Selecting this option will cause any extra data to be copied to the end of the compressed executable.

Skip Shared Sections

Toggle on or off the skipping of compression of shared data sections. Shared data sections are often used by dynamic link libraries so that multiple instances of the module in different process spaces may share data. If this toggle is left OFF, the shared flag is removed from any shared sections and they are compressed as normal. Otherwise, the shared section is skipped and its data is available for sharing across processes.

Backup File

Create a backup of the file before compression. The backup will be named the same as the original, except it will have the “.bak” extension appended to it.

Small/Fast Decompressor

The small decompressor is smaller, yet slower than the fast decompressor. The size difference is about 150 bytes, but the fast decompressor could cause an increase in executable size by as much as 512 bytes.

Skip Checksum

Toggle checksum calculation by decompressor. By default, a checksum is calculated and compared for every decompressed block and once after code reconstruction. If any data corruption is found, a Message Box is displayed alerting the user. Turning checksumming off may decrease decompression and reconstruction time (execution latency) by ~30%.

Plug-ins - Encrypt

Select the encryption plug-in. This plug-in is described in the Plug-ins documentation.

Plug-ins – Pre-operative

Select the pre-operative plug-in. This plug-in is described in the Plug-ins documentation.

Plug-ins - Post-operative

Select the post-operative plug-in. This plug-in is described in the Plug-ins documentation.

Plug-ins – GPA

Select the GetProcAddress hook plug-in. This plug-in is described in the Plug-ins documentation.

Plug-ins - ExtraData

Select the ExtraData plug-in. This plug-in is simply a file of text or binary type that contains data (such as a copyright message) that will be inserted by PECompact into the compressed executable’s slack header space (the header will be expanded if necessary).

Finish Beep

Emit beep when compression of a file is complete.

One Instance

Only allow one instance of PECompact to be active at a time.

Lock Memory in RAM

Lock allocated memory into RAM if possible.

Compressible Resources

This list of resources allows for selection of which resources should be compressed, and which should remain uncompressed and preserved.

Unknown Types (Resources)

This toggle allows you to set the compression of unknown resource types. ActiveX controls should turn this toggle off.

All Shell Icons

Compress all shell icons, leaving none available for display by explorer and other applications.

# of Shell Icons

The maximum number of icons to leave uncompressed and available for display by explorer and other applications. Decreasing this number will result in greater compression of most executables.

 

3.      Menu Options

 

Configuration / Save

Save the current configuration to a file.

Configuration / Save Configuration As

Save the current configuration to a file, and select a new filename.

Configuration / Load Configuration

Load a saved configuration.

Configuration / Restore Defaults

Restore the default configuration.

Help / About

Display the about box and registration status.

Help / Check For Update

Check for an update on Collake Software’s website.

 

B.     Command Line Switches

 

PECompact can be run without any parameters, however it also accepts the following command line syntax:
PECompact [filename] [switches]

/A

Automatically start compression or trimming without any user intervention.

/X

Automatically exit after compression or trimming is complete.

/T[-]

Toggle on/off trim only mode.

/M[-]

Toggle on/off section merging.

/C[-]

Toggle on/off resource restructuring.

/L[-]

Toggle on/off usage of windows DLL loader.

/E[-]

Toggle on/off compression of the export table.

/K[-]

Toggle on/off relocation of the export table.

/I[-]

Toggle on/off compression of all shell icons.

/B[-]

Toggle on/off backup of file.

/O[-]

Toggle on/off copying of overlay.

/S[-]

Toggle on/off stripping of relocations.

/R[-]

Register or unregister shell extension.

/J[-]

Toggle usage of aPLib.

/0-9

Specify compression level for use by JCALG1.

/F[-]

Toggle usage of fast decompression procedure.

/P[-]

Toggle progress bar.

/U[-]

Toggle compression of unknown resources. ActiveX controls should use /U-.

/#[-]

Toggle checksum calculation by decompressor. By default, a checksum is calculated and compared for every decompressed block and once after code reconstruction. If any data corruption is found, a Message Box is displayed alerting the user. Turning checksumming off may decrease decompression and reconstruction time (execution latency) by ~30%.

/![-]

Toggle on or off the skipping of compression of shared data sections. Shared data sections are often used by dynamic link libraries so that multiple instances of the module in different process spaces may share data. If this toggle is left OFF, the shared flag is removed from any shared sections and they are compressed as normal. Otherwise, the shared section is skipped and its data is available for sharing across processes.

/$ConfigFile=FILE

Specify the configuration file to use.

/$StackReserve=00000000

Specify, in hexidecimal, the stack reserve size to set in compressed executables.

/$Encryption=FILE

Specify the encryption plug-in file, given where ‘FILE’.

/$Decryption=FILE

Specify the decryption plug-in file, given where ‘FILE’.

/$PreOperational=FILE

Specify the pre-operational plug-in file, given where ‘FILE’.

/$PostOperational=FILE

Specify the post-operational plug-in file, given where ‘FILE’.

/$GetProcAddressHook=FILE

Specify the GetProcAddressHook plug-in file, given where ‘FILE’.

/$ExtraData=FILE

Specify the ExtraData plug-in file, given where ‘FILE’.

/$UserData=STUFF

Extra input data will be supplied to the Encryption plug-in, if one exist, upon initialization via InitEncryptionPlug-inV2.

 

*Command line switches override a saved configuration.

 

C.     Using with batch files in Windows95/98/Me

 

Windows 95/98/Me do not, by default, wait for termination of a GUI subsystem executable before continuing on with execution of the batch file from which the application was launched. To get around this issue, use the ‘Start’ utility with the command line parameter, ‘/WAIT’.

 

e.g.: Start /WAIT pecompact.exe myfile.exe /A /X

                 

III.      Plug-ins

 

Plug-ins allow for third party developers to embed code into compressed executables to be subsequently invoked at runtime by the PECompact loader. For programming convenience, they are implemented in DLLs with named exports. PECompact retrieves the address for the appropriately named export (each plug-in has a different export name) and then copies the procedure (up to MAX_SIZE) if it is a TRANSIENT plug-in (see plug-in type) to an arbitrary location for execution by the compressed executable at runtime, or merely invokes the plug-in function from the DLL if it is a STATIC plug-in.

 

Starting in PECompact v1.60, a new plug-in interface has been introduced. This interface is much improved over the last one and allows for potential development of PECompact plug-ins in high level languages. All plug-ins use the STDCALL calling convention (please remember ebx, esi, edi, ebp register preservation rules, they will be strictly enforced in later versions).

 

Very useful sample plug-ins written in MASM are located in the PLUG-INSV2.ZIP file of your PECompact installation folder.

 

This new interface is much more robust than the previous. Amongst many of its benefits, it offers a resident data storage in which the all plug-ins may store data and communicate with one another (this data remains intact for both TRANSIENT and STATIC type plug-ins, meaning that STATIC plug-ins may store data here that TRANSIENT plug-ins may subsequently access at runtime). This resident data area, and its size, is passed to each plug-in. Additionally, each plug-in is passed the addresses of LoadLibraryA and GetProcAddress.

 

The two types of plug-ins:
  

               STATIC
               These plug-ins are executed directly in the DLL they reside in. They have no maximum size and no other restrictions.

              

               TRANSIENT

These plug-ins will be copied from the DLL they reside in to the loader placed onto compressed executables. They will be executed at runtime of the
compressed executable. Therefore, these plug-ins have certain restrictions:


1.) They must reside in a contiguous block (both data and code together) starting at the address of their export procedure and must not exceed
maximum size specified.

 

2.) They must calculate and apply a delta offset to all static code and data references.


3.) Please see sample plug-ins for templates and examples.

 

 

         Pre-Operative Plug-in

Brief: This plug-in is copied into the PECompact loader placed into the host executable. It is invoked at runtime before any decompression or
reconstruction of the host executable occurs.

            Export Name: PreOperativePluginV2

            Maximum Size: 512 bytes

            Plug-in Type: TRANSIENT

            C Prototype:

DWORD PreOperativePluginV2(HMODULE pLoadLibrary,

                     LPVOID pGetProcAddress,

                LPVOID pResidentData,

                     DWORD nResidentDataSize,

                     LPVOID pImageBase,

                     PPEC_DATA_BLOCK_INFO pDataBlockInfoArray);

 

ASM Prototype:

PreOperativePluginV2 PROTO stdcall pLoadLibrary:DWORD,\

                pGetProcAddress:DWORD,\

                pResidentData:DWORD,\

                nResidentDataSize:DWORD,\

                pImageBase:DWORD,\

                pDataBlockInfoArray:DWORD

 

            Return Value:

ERROR_SUCCESS (0) = success, continue decompression/reconstruction.

ERROR_FATAL (1) = error, this process should immediately exit.

 

            Parameter Descriptions:

                        pLoadLibrary = pointer to LoadLibraryA.

                        pGetProcAddress = pointer to GetProcAddress.

                        pResidentData = pointer to the resident data storage area.

                        nResidentDataSize = size, in bytes, of the resident data.

                        pImageBase = pointer to the image base of the application.
                        pDataBlockInfoArray = pointer to an array PEC_DATA_BLOCK_INFO records.

                             typedef struct _PEC_DATA_BLOCK_INFO

{

       PVOID pBlockRVA;

       ULONG nCompressedSize;

} PEC_DATA_BLOCK_INFO, *PPEC_DATA_BLOCK_INFO;       

            Notes: 

None.

 

         

         Post-Operative Plug-in

Brief: This plug-in is copied into the PECompact loader placed into the host executable. It is invoked at runtime after all decompression and reconstruction of the host executable is complete and control is about to be passed back to the original entry point.

            Export Name: PostOperativePluginV2

            Maximum Size: 512 bytes

            Plug-in Type: TRANSIENT

C Prototype:

     DWORD PostOperativePluginV2(HMODULE pLoadLibrary,

                LPVOID pGetProcAddress,

                LPVOID pResidentData,

                DWORD nResidentDataSize);

 

ASM Prototype:

PostOperativePluginV2 PROTO stdcall pLoadLibrary:DWORD,\

                pGetProcAddress:DWORD,\

                pResidentData:DWORD,\

                nResidentDataSize:DWORD

            Return Value:

ERROR_SUCCESS (0) = success, continue decompression/reconstruction.

ERROR_FATAL (1) = error, this process should immediately exit.

            Parameter Descriptions:

                        pLoadLibrary = pointer to LoadLibraryA.

                        pGetProcAddress = pointer to GetProcAddress.

                        pResidentData = pointer to the resident data storage area.

                        nResidentDataSize = size, in bytes, of the resident data.

            Notes: 

None.  

         

         Encryption Plug-in: Function: DecryptPlug-inV2

Brief: This plug-in is copied into the PECompact loader placed into the host executable. It is invoked at runtime before each data block is sent to the decompression procedure for processing.

            Export Name: PostOperativePluginV2

            Maximum Size: 1024 bytes

            Plug-in Type: TRANSIENT

C Prototype:                             

DWORD DecryptPluginV2(HMODULE pLoadLibrary,

          LPVOID pGetProcAddress,

          LPVOID pResidentData,

DWORD nResidentDataSize,

                   LPVOID pSource,

                   DWORD nDataSize,

                   LPVOID pDestination);

 

ASM Prototype:

DecryptPluginV2 PROTO stdcall pLoadLibrary:DWORD,\

                pGetProcAddress:DWORD,\

                pResidentData:DWORD,\

                nResidentDataSize:DWORD,\

                pSource:DWORD,\

                nDataSize:DWORD,\

                pDestination:DWORDs              

 

            Return Value: Size of processed data or zero if error.

            Parameter Descriptions:

                        pLoadLibrary = pointer to LoadLibraryA.

                        pGetProcAddress = pointer to GetProcAddress.

                        pResidentData = pointer to the resident data storage area.

                        nResidentDataSize = size, in bytes, of the resident data.

                        pSource = pointer to the start of the data block.

                        nDataSize = size of the data block pointed to be pSource.

                        pDestination = pointer to the destination buffer for the processed data block.

            Notes:             

This plug-in must undo what EncryptPlug-inV2 did to the data block at time of compression and store the result in the buffer pointed to by pDestination. To help in data alignment and to provide extra storage, each buffer is guaranteed to be of this size:

                                    ((nDataSize+15)/8)*8

                        This plug-in should return the new size of the data.

                                               

 

         Encryption Plug-in: Function: EncryptPluginV2

Brief: This function is called by PECompact itself while the host executable is being compressed. It is invoked once for each data block, immediately after compression of that data block.

            Export Name: EncryptPluginV2

            Maximum Size: no maximum.

            Plug-in Type: STATIC

C Prototype:

DWORD EncryptPluginV2(HMODULE pLoadLibrary,

                   LPVOID pGetProcAddress,

                   LPVOID pResidentData,

                   DWORD nResidentDataSize,

                   LPVOID pSource,

                   DWORD nDataSize,

                   LPVOID pDestination);

 

ASM Prototype:

EncryptPluginV2 PROTO stdcall pLoadLibrary:DWORD,\

                pGetProcAddress:DWORD,\

                pResidentData:DWORD,\

                nResidentDataSize:DWORD,\

                pSource:DWORD,\

                nDataSize:DWORD,\

                pDestination:DWORDs  

           

            Return Value: Size of processed data or zero if error.

            Parameter Descriptions:

                        pLoadLibrary = pointer to LoadLibraryA.

                        pGetProcAddress = pointer to GetProcAddress.

                        pResidentData = pointer to the resident data storage area.

                        nResidentDataSize = size, in bytes, of the resident data.

                        pSource = pointer to the start of the data block.

                        nDataSize = size of the data block pointed to be pSource.

                        pDestination = pointer to the destination buffer for the processed data block.

            Notes:             

This plug-in must undo what DecryptPlug-inV2 will do to the data block and store the resulting data in the buffer pointed to by pDestination. To help in data alignment and to provide extra storage, each buffer is guaranteed to be of this size:

                                    ((nDataSize+15)/8)*8

                        This plug-in should return the new size of the data.

                       

 

         Encryption Plug-in: Function: InitEncryptionPluginV2

Brief: This function is called by PECompact itself while the host executable is being compressed. It is invoked once at the beginning of compression and before any call to EncryptPlug-inV2 is done.

            Export Name: InitEncryptionPluginV2

            Maximum Size: no maximum.

            Plug-in Type: STATIC

C Prototype:

DWORD InitEncryptionPluginV2(HMODULE pLoadLibrary,

LPVOID pGetProcAddress,

LPVOID pResidentData,

DWORD nResidentDataSize,

HINSTANCE hInstance,

LPVOID pUserData,

DWORD nUserDataLen);

 

ASM Prototype:

InitEncryptionPluginV2 PROTO stdcall pLoadLibrary:DWORD,\

                pGetProcAddress:DWORD,\

                pResidentData:DWORD,\

                nResidentDataSize:DWORD,\

                hInstance:DWORD,\

                pUserData:DWORD,\

                nUserDataLen:DWORD

            Return Value:

                        ERROR_SUCCESS (0) = successful termination.

ERROR_FATAL (1) = there was an error that requires the compressor to stop compression of the executable.

ERROR_NONFATAL (2) = there was an error, but compression of the executable should still continue.

                                                                       

            Parameter Descriptions:

                        pLoadLibrary = pointer to LoadLibraryA.

                        pGetProcAddress = pointer to GetProcAddress.

                        pResidentData = pointer to the resident data storage area.

                        nResidentDataSize = size, in bytes, of the resident data.

                        hInstance = module handle of the parent instance.

pUserData = pointer to a block of optional text that may have been provided by the user via the command line parameter “/$UserData=”.

                        nUserDataLen = length of the user data.           

            Notes:             

                        None.

 

          GetProcAddressHook Plug-in

Brief: This function is called by the PECompact loader at runtime of the compressed executable. It is invoked every time the loader needs to retrieve an address of an API. This plugin is intended to facilitate API hooking.

            Export Name: GetProcAddressHookPluginV2

            Maximum Size: no maximum.

            Plug-in Type: STATIC

C Prototype:

DWORD GetProcAddressHookPluginV2(HMODULE pLoadLibrary,

                LPVOID pGetProcAddress,

                LPVOID pResidentData,

                DWORD nResidentDataSize,

                HMODULE hModule,

                LPSTR pszApiName);

 

ASM Prototype:

GetProcAddressHookPluginV2 PROTO stdcall pLoadLibrary:DWORD,\

                pGetProcAddress:DWORD,\

                pResidentData:DWORD,\

                nResidentDataSize:DWORD,\
                        hModule:DWORD,\

                   pszApiName:DWORD

            Return Value:

                        Zero if error, else address of API indicated by hModule and pszApiName.                                                                   

            Parameter Descriptions:

                        pLoadLibrary = pointer to LoadLibraryA.

                        pGetProcAddress = pointer to GetProcAddress.

                        pResidentData = pointer to the resident data storage area.

                        nResidentDataSize = size, in bytes, of the resident data.

                        hModule = module handle for the API being imported.
                        pszApiName = Pointer to API name *OR* ordinal number (follows same rules as GetProcAddress).

            Notes:             

                        None.

 

 

ExtraData Plug-in

his plug-in differs from the others, in that it is merely a text or data file containing data that will be inserted   verbatim into the compressed portable executable. It will  be inserted following the object table, which is located immediately after the portable executable header. The ExtraData plug-in is intended to facilitate introduction of copyright messages into the binary, but can be used to insert any other data. It has a maximum size of 512 bytes.

 

 

 

IV.      Registration / Purchasing Information

 

For purchasing information please visit http://www.CollakeSoftware.com/Purchase.htm .